﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BbsbWebService.Enums;
using System.Runtime.Serialization;
using System.Xml.Linq;

namespace BbsbWebService.Tasks
{
    [DataContract]
    public class ScheduledTask : BaseTask
    {
        public ScheduledTask() { }

        public ScheduledTask(WeekDay days, DateTime time)
            : base(time)
        {
            Days = days;
            SetNextAlarmMain();
        }

        public ScheduledTask(XElement element)
            : base(element)
        {
            Days = (WeekDay)element.GetChildValueFromElement<int>("Days");
            SetNextAlarmMain();
        }

        [DataMember]
        public WeekDay Days;

        protected override void SetNextAlarm()
        {
            if (NextAlarm.HasValue && Days != WeekDay.None)
            {
                DateTime last = NextAlarm.Value;
                do
                {
                    last = last.AddDays(1);
                }
                while (!IsDateSelected(last));
                NextAlarm = last;
            }
        }

        protected override string AdditionalDesctiption
        {
            get { return string.Format(" on these days: {0}", Days); }
        }

        protected override IEnumerable<XElement> GetRestAsXElement()
        {
            yield return new XElement("Days", (int)Days);
        }

        private bool IsDateSelected(DateTime date)
        {
            WeekDay day = GetDayFromDate(date);
            return DayIsSelected(day);
        }

        private bool DayIsSelected(WeekDay day)
        {
            return (Days & day) == day;
        }

        private WeekDay GetDayFromDate(DateTime date)
        {
            return date.DayOfWeek.ToString().ToEnum<WeekDay>();
        }

        protected override void Validate(ref Classes.ValidationState state)
        {
            base.Validate(ref state);

            if ((int)Days == 0)
                state.AddError("Must have at least one day selected");
        }
    }
}
